package com.github.icloudpay.pay.core.service.schedule;

import java.math.BigDecimal;
import java.util.List;

import javax.xml.bind.JAXBException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.github.icloudpay.pay.core.biz.PayOrderBiz;
import com.github.icloudpay.pay.core.biz.PaySerialBiz;
import com.github.icloudpay.pay.core.biz.RefundOrderBiz;
import com.github.icloudpay.pay.core.biz.RefundSerialBiz;
import com.github.icloudpay.pay.core.entity.PayChannelInterface;
import com.github.icloudpay.pay.core.entity.PayOrder;
import com.github.icloudpay.pay.core.entity.PaySerial;
import com.github.icloudpay.pay.core.entity.RefundOrder;
import com.github.icloudpay.pay.core.entity.RefundSerial;
import com.github.icloudpay.pay.core.inter.QueryRefundStatusService;
import com.github.icloudpay.pay.core.inter.schedule.RefundStatusService;
import com.github.icloudpay.pay.core.mapper.PayChannelInterfaceMapper;
import com.github.icloudpay.pay.core.service.refund.RefundCallbackService;
import com.github.icloudpay.pay.core.util.DateUtil;
import com.github.icloudpay.pay.core.util.SpringContextHolder;
import com.github.wxiaoqi.security.common.admin.pay.request.CallbackRequest;
import com.github.wxiaoqi.security.common.admin.pay.request.QueryRefundStatusRequest;
import com.github.wxiaoqi.security.common.admin.pay.response.QueryRefundStatusResponse;


/**
 * 退款状态查询调度
 * @author hexufeng
 *
 */
@Service("refundStatusService")
public class RefundStatusServiceImpl implements RefundStatusService{

	private static final Logger logger = LoggerFactory.getLogger(RefundStatusServiceImpl.class);

	@Autowired
	private RefundSerialBiz refundSerialBiz;
	@Autowired
	private RefundOrderBiz refundOrderBiz;
	@Autowired
	private PayChannelInterfaceMapper payChannelInterfaceMapper;
	@Autowired
	private PaySerialBiz paySerialBiz;
	@Autowired
	private PayOrderBiz payOrderBiz;
	@Autowired
	private RefundCallbackService refundCallbackService;

	@Override
	public void RefundStatus() {

		String endDateTime = DateUtil.getStandardDateTime();

		logger.info("定时查询退款流水状态,时间为：{}",endDateTime);

		int refundSerialCount = refundSerialBiz.getCountByDateTime(endDateTime);
		if(refundSerialCount == 0){
			logger.info("时间为：{}之前,定时查询退款流水状态,退款流水表中不存在退款处理中的流水", endDateTime);
			return;
		}
		logger.info("需要去第三方支付公司查询的退款流水数量为：{}",refundSerialCount);

		int count = refundSerialCount%500==0?(refundSerialCount/500):((refundSerialCount/500)+1);
		for(int i = 0; i < count; i++){
			List<RefundSerial> refundSerialList = refundSerialBiz.queryRefundSerialList(endDateTime, 1, 500);
			if(refundSerialList == null || refundSerialList.size() == 0){
				logger.info("时间为：{}之前,定时查询退款状态,退款订单表中不存在退款处理中的订单", endDateTime);
				return;
			}
			for(int j = 0; j < refundSerialList.size(); j++){
				ordStatusHandle(refundSerialList.get(j));
			}
		}
	}

	/**
	 * 向第三方查询退款结果并更新状态
	 * @param paySerial
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	private void ordStatusHandle(RefundSerial refundSerial){
		RefundOrder refundOrder = new RefundOrder();
		refundOrder.setPlatformId(refundSerial.getPlatformId());
		refundOrder.setRefundOrderNo(refundSerial.getRefundOrderNo());
		RefundOrder selectRefundOrder = refundOrderBiz.selectOne(refundOrder);
		if(null == selectRefundOrder){
			logger.info("订单号为：{}的退款订单不存在", refundSerial.getRefundOrderNo());
			return;
		}
		
		PayOrder payOrder = new PayOrder();
		payOrder.setPayOrderNo(selectRefundOrder.getPayOrderNo());
		payOrder.setPlatformId(selectRefundOrder.getPlatformId());
		PayOrder selectPayOrder = payOrderBiz.selectOne(payOrder);
		if(selectPayOrder == null){
			logger.info("订单号为：{}的支付订单不存在", selectRefundOrder.getPayOrderNo());
			return;
		}

		PaySerial paySerial = new PaySerial();
		paySerial.setPayOrderNo(selectRefundOrder.getPayOrderNo());
		paySerial.setPlatformId(selectRefundOrder.getPlatformId());
		paySerial.setPayStatus("00");//支付成功
		PaySerial selectPaySerial = paySerialBiz.selectOne(paySerial);
		if(selectPaySerial == null){
			logger.info("订单号为：{}的支付流水不存在", selectRefundOrder.getPayOrderNo());
			return;
		}

		//根据支付通道查询查询请求方法
		PayChannelInterface payChannelInterface = new PayChannelInterface();
		payChannelInterface.setPayChannelNo(selectPaySerial.getPayChannelNo());
		payChannelInterface.setTradeType("03");//退款查询
		PayChannelInterface selectInterface = payChannelInterfaceMapper.selectOne(payChannelInterface);
		if(null == selectInterface || null == selectInterface.getServiceName()){
			logger.info("退款通道为：{}的信息未配置", selectPaySerial.getPayChannelNo());
			return;
		}
		QueryRefundStatusService queryRefundStatusService = SpringContextHolder.getBean(selectInterface.getServiceName());

		QueryRefundStatusRequest queryRefundStatusRequest = new QueryRefundStatusRequest();
		queryRefundStatusRequest.setMerId(selectPayOrder.getMerchantId());
		queryRefundStatusRequest.setMchtRefundOrderNo(refundSerial.getSerialNo());
		queryRefundStatusRequest.setOutTradeNo(selectPaySerial.getSerialNo());
		queryRefundStatusRequest.setPayChannelNo(selectPaySerial.getPayChannelNo());
		queryRefundStatusRequest.setPayCompanyNo(selectPaySerial.getPayCompanyNo());
		queryRefundStatusRequest.setPlatformId(refundSerial.getPlatformId());
		QueryRefundStatusResponse queryRefundStatusResponse = new QueryRefundStatusResponse();
		try {
			queryRefundStatusResponse = queryRefundStatusService.queryRefundStatus(queryRefundStatusRequest);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		if(!queryRefundStatusResponse.isSuccess()){
			logger.info("向第三方查询退款结果失败,订单号.....{}", refundSerial.getRefundOrderNo());
			return;
		}
		
		CallbackRequest callbackRequest = new CallbackRequest();
		callbackRequest.setRequestNo(refundSerial.getSerialNo());
		callbackRequest.setOrderAmt(new BigDecimal(queryRefundStatusResponse.getRefundFee()));
		callbackRequest.setRemoteTxJournalNo(queryRefundStatusResponse.getResJrnNo());
		callbackRequest.setPayChannelNo(selectPaySerial.getPayChannelNo());
		if ("00".equals(queryRefundStatusResponse.getRefundStatus())) {
			logger.info("退款订单号为{}的退款交易状态为成功", selectRefundOrder.getRefundOrderNo());
			callbackRequest.setStatus("00");
        } else if ("01".equals(queryRefundStatusResponse.getRefundStatus())) {
        	logger.info("退款订单号为{}的退款交易状态为失败", selectRefundOrder.getRefundOrderNo());
        	callbackRequest.setStatus("01");
        } else {
        	logger.info("退款订单号为{}的退款交易状态为退款处理中", selectRefundOrder.getRefundOrderNo());
            return;
        }
		refundCallbackService.callBack(callbackRequest);
	}
}
